package file_create_tab

import (
	"fmt"
	"strconv"
	"strings"

	"file_explorer/common/consts"
	"file_explorer/common/log"
	"file_explorer/common/util"
	"file_explorer/model"
	"file_explorer/service"
	"file_explorer/view/components/main_panel/fe_tab"
	"file_explorer/view/packed_widgets"
	"file_explorer/view/store"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
)

type FileCreateTab struct {
	fe_tab.DefaultTab

	createList   *widget.List
	submitButton *packed_widgets.Button

	objItemMap map[fyne.CanvasObject]*FileCreateItem

	tabCtx *store.FileCreateTabContext
}

func (tab *FileCreateTab) createListUpdateItem(index widget.ListItemID, obj fyne.CanvasObject) {
	item := tab.objItemMap[obj]
	fileInfo := tab.tabCtx.CreateFileInfos[index]

	if item.DeleteButton.OnTapped == nil {
		item.DeleteButton.OnTapped = func() {
			log.Info("移除新建项目%d", index)
			delete(tab.objItemMap, obj)
			tab.tabCtx.CreateFileInfos = append(tab.tabCtx.CreateFileInfos[:index], tab.tabCtx.CreateFileInfos[index+1:]...)
			tab.createList.Refresh()
		}
	}

	if item.TypeSelect.OnChanged == nil {
		item.TypeSelect.OnChanged = func(itemType string) {
			fileInfo.Type = consts.FileTypeStrMap[itemType]
		}
	}

	if item.NameEntry.Validator == nil {
		item.NameEntry.Validator = func(name string) error {
			name = strings.TrimSpace(name)
			path := util.PathJoin(tab.tabCtx.Path, name)
			if util.PathExists(path) {
				return fmt.Errorf("file already exists")
			}
			return nil
		}
	}
	if item.NameEntry.OnChanged == nil {
		item.NameEntry.OnChanged = func(name string) {
			name = strings.TrimSpace(name)
			fileInfo.Name = name
		}
	}

	if item.ScoreEntry.OnChanged == nil {
		item.ScoreEntry.OnChanged = func(scoreStr string) {
			scoreStr = strings.TrimSpace(scoreStr)
			score, err := strconv.Atoi(scoreStr)
			if err == nil {
				fileInfo.SetScore(&score)
			} else if len(scoreStr) == 0 {
				fileInfo.SetScore(nil)
			}
		}
	}

	if item.TagEntry.OnChanged == nil {
		item.TagEntry.OnChanged = func(tagsStr string) {
			rawTags := strings.Split(tagsStr, ",")
			tags := make([]string, 0, len(rawTags))
			for _, rawTag := range rawTags {
				rawTag = strings.TrimSpace(rawTag)
				if len(rawTag) > 0 {
					tags = append(tags, rawTag)
				}
			}
			fileInfo.SetTags(tags)
		}
	}

	if item.UrlEntry.OnChanged == nil {
		item.UrlEntry.OnChanged = func(url string) {
			url = strings.TrimSpace(url)
			fileInfo.SetUrl(&url)
		}
	}

	if item.NoteEntry.OnChanged == nil {
		item.NoteEntry.OnChanged = func(note string) {
			note = strings.TrimSpace(note)
			fileInfo.SetNote(&note)
		}
	}
}

func (tab *FileCreateTab) submitCreate() error {
	hasMetadata := false

	for _, fileInfo := range tab.tabCtx.CreateFileInfos {
		if len(fileInfo.Name) == 0 {
			continue
		}

		fileInfo.FormatMetadata()
		if fileInfo.Metadata != nil {
			hasMetadata = true
		}

		err := service.CreateFile(fileInfo)
		if err != nil {
			packed_widgets.NotifyError("创建%s%s失败，路径：%s，错误：%s", fileInfo.GetTypeStr(), fileInfo.Name, fileInfo.Dir, err.Error())
			return err
		}

		log.Info("创建%s%s成功，路径：%s", fileInfo.GetTypeStr(), fileInfo.Name, fileInfo.Dir)
	}

	if !hasMetadata {
		log.Info("没有待写入元数据")
		return nil
	}

	// 更新元数据
	metadata, _ := service.ReadLatestMetadata(tab.tabCtx.Path)
	if metadata == nil {
		metadata = &model.FileMetadataMap{}
	}

	for _, fileInfo := range tab.tabCtx.CreateFileInfos {
		metadata.SetFileMetadata(fileInfo)
	}

	name, err := service.CreateMetadata(tab.tabCtx.Path, metadata)
	if err != nil {
		packed_widgets.NotifyError("写入元数据失败，路径：%s，错误：%s", tab.tabCtx.Path, err.Error())
		return err
	}

	log.Info("写入元数据成功，元文件名：%s，路径：%s", name, tab.tabCtx.Path)

	return nil
}

func NewFileCreateTab(tabCtx store.TabContext) *FileCreateTab {
	tab := &FileCreateTab{
		tabCtx:     tabCtx.(*store.FileCreateTabContext),
		objItemMap: make(map[fyne.CanvasObject]*FileCreateItem),
	}

	// 初始状态添加一个item占位
	tab.tabCtx.CreateFileInfos = append(tab.tabCtx.CreateFileInfos, &model.FileInfo{
		Dir:  tab.tabCtx.Path,
		Type: consts.FileTypeRegular,
	})

	// 添加项目按钮
	addItemButton := packed_widgets.NewButton("添加", theme.ContentAddIcon(), func() {
		log.Info("新增创建项目")
		tab.tabCtx.CreateFileInfos = append(tab.tabCtx.CreateFileInfos, &model.FileInfo{
			Dir:  tab.tabCtx.Path,
			Type: consts.FileTypeRegular,
		})
		tab.createList.Refresh()
	})

	// 创建submit按钮
	tab.submitButton = packed_widgets.NewButton("提交", theme.ConfirmIcon(), func() {
		err := tab.submitCreate()
		if err != nil {
			packed_widgets.NotifyError(err.Error())
			return
		}
		tab.tabCtx.GetGlobalContext().RemoveTab(tab.tabCtx.GetTabItem())
		tab.tabCtx.GetGlobalContext().RefreshTabIfExists(tab.tabCtx.Path)
	})

	// 工具栏
	toolbar := container.NewBorder(nil, nil,
		addItemButton,
		tab.submitButton,
	)

	// 创建项目列表
	tab.createList = widget.NewList(
		func() int {
			return len(tab.tabCtx.CreateFileInfos)
		},
		func() fyne.CanvasObject {
			item := newFileCreateItem()
			tab.objItemMap[item] = item
			return item.Container
		},
		tab.createListUpdateItem,
	)

	tab.Container = container.NewBorder(toolbar, nil, nil, nil, tab.createList)

	return tab
}
